package cn.changeforyou.web.nutz.common.security;

import cn.changeforyou.web.blog.po.User;
import cn.changeforyou.utils.matcher.url.impl.MockShiroIniUrlMattcher;
import com.alibaba.druid.util.StringUtils;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.mvc.ActionContext;
import org.nutz.mvc.ActionFilter;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.View;
import org.nutz.mvc.view.HttpStatusView;

/**
 * @author zhyu
 */
@Slf4j
public class JwtFilter implements ActionFilter {

    private MockShiroIniUrlMattcher matcher;
    private boolean initOk;

    private JwtTokenUtil jwtTokenUtil;
    private SecurityConfig config;
    private AuthUtil authUtil;

    @Override
    public View match(ActionContext actionContext) {
        if (!initOk) {
            init(actionContext);
        }
        if (null == matcher) {
            return null;
        }
        boolean pass = false;
        //1. 有session的通过

        String authHeader = actionContext.getRequest().getHeader(config.getTokenHeader());
        if (StringUtils.isEmpty(authHeader)) {
            String path = Mvcs.getRequestPath(actionContext.getRequest());
            if (matcher.isMatched(path)) {
                pass = true;
            }
        } else if (authHeader.startsWith(config.getTokenHead())) {
            String authToken = authHeader.substring(config.getTokenHead().length());
            try {
                User user = jwtTokenUtil.getUserFromToken(authToken);
                authUtil.setUser(user);
                pass = true;
            }catch (AuthException e) {
            }
        }
        if (pass || actionContext.getRequest().getMethod().equals("options")) {
            return null;
        }
        HttpStatusView view = new HttpStatusView(403);
        view.setBody("please login!");
        return view;
    }

    private void init(ActionContext actionContext) {
        synchronized (this) {
            if (!initOk) {
                config = actionContext.getIoc().get(SecurityConfig.class);
                jwtTokenUtil = actionContext.getIoc().get(JwtTokenUtil.class);
                authUtil = actionContext.getIoc().get(AuthUtil.class);
                List<String> whiteUrls = config.getWhiteUrls();
                if (CollectionUtils.isNotEmpty(whiteUrls)) {
                    matcher = new MockShiroIniUrlMattcher();
                    matcher.setPattern(whiteUrls.toArray(new String[whiteUrls.size()]));
                }
                initOk = true;
            }
        }
    }
}
